package com.ruoyi.wms.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.core.utils.MapstructUtils;
import com.ruoyi.common.mybatis.core.page.PageQuery;
import com.ruoyi.common.mybatis.core.page.TableDataInfo;
import com.ruoyi.wms.domain.bo.employee.EmployeeSalaryBo;
import com.ruoyi.wms.domain.entity.employee.EmployeeSalary;
import com.ruoyi.wms.domain.entity.employee.Employees;
import com.ruoyi.wms.domain.entity.employee.KMetricDetails;
import com.ruoyi.wms.domain.entity.employee.PMetricDetails;
import com.ruoyi.wms.domain.vo.EmployeeSalaryVo;
import com.ruoyi.wms.mapper.EmployeeSalaryMapper;
import com.ruoyi.wms.mapper.EmployeesMapper;
import com.ruoyi.wms.mapper.KMetricDetailsMapper;
import com.ruoyi.wms.mapper.PMetricDetailsMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 员工薪酬Service业务层处理
 *
 * @author 邓滔滔
 * @date 2024-11-29
 */
@RequiredArgsConstructor
@Service
public class EmployeeSalaryService {

    private final EmployeeSalaryMapper employeeSalaryMapper;
    private final KMetricDetailsMapper kMetricDetailsMapper;

    private final EmployeesMapper employeesMapper;

    private final PMetricDetailsMapper pMetricDetailsMapper;

    /**
     * 查询员工薪酬
     */
    public EmployeeSalaryVo queryById(Long id) {
        return employeeSalaryMapper.selectVoById(id);
    }

    /**
     * 查询员工薪酬列表
     */
    public TableDataInfo<EmployeeSalaryVo> queryPageList(EmployeeSalaryBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<EmployeeSalary> lqw = buildQueryWrapper(bo);
        //计算员工薪酬
        if (bo.getAllowance() != null && bo.getBonus() != null && bo.getBaseSalary() != null) {
            List<EmployeeSalary> employeeSalaries = employeeSalaryMapper.selectList(lqw);
            for (EmployeeSalary employeeSalary : employeeSalaries) {
                if (employeeSalary != null) {
                    BigDecimal totalSalay = employeeSalary.getBaseSalary().add(employeeSalary.getAllowance()).add(employeeSalary.getBonus());
                    employeeSalary.setNetSalary(totalSalay);
                    employeeSalaryMapper.updateById(employeeSalary);
                }
            }
        }
        Page<EmployeeSalaryVo> result = employeeSalaryMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询员工薪酬列表
     */
    public List<EmployeeSalaryVo> queryList(EmployeeSalaryBo bo) {
        LambdaQueryWrapper<EmployeeSalary> lqw = buildQueryWrapper(bo);
        return employeeSalaryMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<EmployeeSalary> buildQueryWrapper(EmployeeSalaryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<EmployeeSalary> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getEmployeeId() != null, EmployeeSalary::getEmployeeId, bo.getEmployeeId());
        lqw.eq(bo.getStatus() != null, EmployeeSalary::getStatus, bo.getStatus());
        lqw.between(params.get("beginPayPeriod") != null && params.get("endPayPeriod") != null,
            EmployeeSalary::getPayPeriod, params.get("beginPayPeriod"), params.get("endPayPeriod"));
        return lqw;
    }

    /**
     * 新增员工薪酬
     */
    public void insertByBo(EmployeeSalaryBo bo) {
        EmployeeSalary add = MapstructUtils.convert(bo, EmployeeSalary.class);
        //查询k项薪资
        Date payPeriod = bo.getPayPeriod();
        DateTime begin = DateUtil.beginOfMonth(payPeriod);
        DateTime end = DateUtil.endOfMonth(payPeriod);
        KMetricDetails kMetricDetails = getkMetricDetails(bo.getEmployeeId(), begin, end);
        if (kMetricDetails != null) {
            if (add != null) {
                add.setBaseSalary(kMetricDetails.getKTotalSalay());
            }
        }
        //查询p项薪资
        PMetricDetails pMetricDetails = getpMetricDetails(bo.getEmployeeId(), begin, end);
        if (pMetricDetails != null) {
            if (add != null) {
                add.setAllowance(pMetricDetails.getPSalay());
            }
        }

        if (bo.getAllowance() != null && bo.getBaseSalary() != null && bo.getBonus() != null) {
            //计算员工薪酬
            bo.setNetSalary(bo.getAllowance().add(bo.getBaseSalary()).add(bo.getBonus()));
        }

        employeeSalaryMapper.insert(add);
    }

    /**
     * 根据员工id和薪酬周期查询员工薪酬-p
     *
     * @param employeeId
     * @param begin
     * @param end
     * @return
     */
    private PMetricDetails getpMetricDetails(Long employeeId, DateTime begin, DateTime end) {
        return pMetricDetailsMapper.selectOne(Wrappers.<PMetricDetails>lambdaQuery()
            .eq(PMetricDetails::getEmployeeId, employeeId)
            .between(PMetricDetails::getCalculationPeriod, begin, end));
    }

    /**
     * 根据员工id和薪酬周期查询员工薪酬-k
     *
     * @param
     * @return
     */
    private KMetricDetails getkMetricDetails(Long employeeId, DateTime begin, DateTime end) {
        //查询k项薪资
        Long storeId = employeesMapper.selectOne(Wrappers.<Employees>lambdaQuery().eq(Employees::getId, employeeId)).getStoreId();
        //查询当月k项薪资
        return kMetricDetailsMapper.selectOne(Wrappers.<KMetricDetails>lambdaQuery()
            .eq(KMetricDetails::getStoreId, storeId)
            .between(KMetricDetails::getCalculationPeriod, begin, end));
    }

    /**
     * 修改员工薪酬
     */
    public void updateByBo(EmployeeSalaryBo bo) {
        //查询k项薪资
        Date payPeriod = bo.getPayPeriod();
        DateTime begin = DateUtil.beginOfMonth(payPeriod);
        DateTime end = DateUtil.endOfMonth(payPeriod);
        KMetricDetails kMetricDetails = getkMetricDetails(bo.getEmployeeId(), begin, end);
        bo.setBaseSalary(kMetricDetails.getKTotalSalay());
        //查询p项薪资
        PMetricDetails pMetricDetails = getpMetricDetails(bo.getEmployeeId(), begin, end);
        bo.setAllowance(pMetricDetails.getPSalay());
        if (bo.getAllowance() != null && bo.getBaseSalary() != null && bo.getBonus() != null) {
            //计算员工薪酬
            bo.setNetSalary(bo.getAllowance().add(bo.getBaseSalary()).add(bo.getBonus()));
        }
        EmployeeSalary update = MapstructUtils.convert(bo, EmployeeSalary.class);

        employeeSalaryMapper.updateById(update);
    }

    /**
     * 批量删除员工薪酬
     */
    public void deleteByIds(Collection<Long> ids) {
        employeeSalaryMapper.deleteBatchIds(ids);
    }
}
